<script setup lang="ts">
import { ref, computed } from 'vue'
import { ArticleExporter, type Article as ExportArticle, type ExportOptions } from '@/utils/export'
import type { Article as BlogArticle } from '@/types/blog.types'
import { PhDownload, PhFileText, PhCheck, PhX, PhSpinner, PhWarning } from '@phosphor-icons/vue'

defineOptions({
  name: 'ArticleExporter',
})

/**
 * Props 定义
 */
interface Props {
  article: BlogArticle
  elementId?: string
}

const props = withDefaults(defineProps<Props>(), {
  elementId: 'article-content',
})

/**
 * 导出状态
 */
const isExporting = ref(false)
const showExportModal = ref(false)
const exportProgress = ref('')
const exportError = ref('')

/**
 * 导出选项
 */
const exportOptions = ref<ExportOptions>({
  filename: '',
  includeMetadata: true,
})

/**
 * 计算属性
 */
const canExport = computed(() => {
  return !isExporting.value
})

const defaultFilename = computed(() => {
  return props.article.title.replace(/[^\w\s-]/g, '').replace(/\s+/g, '-')
})

/**
 * 将BlogArticle转换为ExportArticle
 */
const convertToExportArticle = (blogArticle: BlogArticle): ExportArticle => {
  return {
    id: String(blogArticle.id),
    title: blogArticle.title,
    content: blogArticle.content,
    htmlContent: blogArticle.htmlContent,
    author: blogArticle.author.name,
    publishDate: String(blogArticle.publishDate || blogArticle.createdAt),
    tags: blogArticle.tags.map((tag) => tag.name),
    category: blogArticle.category.name,
    excerpt: blogArticle.excerpt,
  }
}

/**
 * 打开导出模态框
 */
const openExportModal = (): void => {
  exportOptions.value.filename = defaultFilename.value
  exportError.value = ''
  showExportModal.value = true
}

/**
 * 关闭导出模态框
 */
const closeExportModal = (): void => {
  if (!isExporting.value) {
    showExportModal.value = false
  }
}

/**
 * 执行导出
 */
const performExport = async (): Promise<void> => {
  if (!canExport.value) return

  try {
    isExporting.value = true
    exportError.value = ''
    exportProgress.value = '正在导出 Markdown...'

    // 确保文件名有.md后缀
    const filename = exportOptions.value.filename || defaultFilename.value
    const finalFilename = filename.endsWith('.md') ? filename : `${filename}.md`

    await ArticleExporter.exportToMarkdown(convertToExportArticle(props.article), {
      ...exportOptions.value,
      filename: finalFilename,
    })

    exportProgress.value = '导出完成！'

    // 2秒后关闭模态框
    setTimeout(() => {
      closeExportModal()
      exportProgress.value = ''
    }, 2000)
  } catch (error) {
    console.error('导出失败:', error)
    exportError.value = error instanceof Error ? error.message : '导出失败，请重试'
    exportProgress.value = ''
  } finally {
    isExporting.value = false
  }
}
</script>

<template>
  <div class="article-exporter">
    <!-- 导出触发器插槽 -->
    <div class="export-trigger">
      <slot name="trigger" :is-exporting="isExporting" :open-modal="openExportModal">
        <!-- 默认导出按钮 -->
        <button
          @click="openExportModal"
          class="btn btn-outline btn-sm export-btn"
          :disabled="isExporting"
          :title="`导出 ${article.title} 为 Markdown 格式`"
        >
          <PhSpinner v-if="isExporting" :size="16" class="animate-spin mr-2" />
          <PhDownload v-else :size="16" class="mr-2" />
          <span>导出</span>
        </button>
      </slot>
    </div>

    <!-- 导出模态框 -->
    <Transition
      enter-active-class="transition-all duration-300 ease-out"
      enter-from-class="opacity-0"
      enter-to-class="opacity-100"
      leave-active-class="transition-all duration-200 ease-in"
      leave-from-class="opacity-100"
      leave-to-class="opacity-0"
    >
      <div
        v-if="showExportModal"
        class="fixed inset-0 bg-black/50 backdrop-blur-sm z-[100] flex items-center justify-center p-4"
        @click="closeExportModal"
      >
        <Transition
          enter-active-class="transition-all duration-300 ease-out"
          enter-from-class="transform scale-95 opacity-0"
          enter-to-class="transform scale-100 opacity-100"
          leave-active-class="transition-all duration-200 ease-in"
          leave-from-class="transform scale-100 opacity-100"
          leave-to-class="transform scale-95 opacity-0"
        >
          <div
            v-if="showExportModal"
            @click.stop
            class="export-modal bg-base-100 rounded-2xl shadow-2xl border border-base-300 w-full max-w-2xl max-h-[90vh] overflow-hidden"
          >
            <!-- 模态框头部插槽 -->
            <slot name="modal-header" :close-modal="closeExportModal" :is-exporting="isExporting">
              <div
                class="modal-header flex items-center justify-between p-6 border-b border-base-300"
              >
                <h2 class="text-xl font-bold text-base-content flex items-center gap-3">
                  <PhDownload :size="24" />
                  导出文章
                </h2>
                <button
                  @click="closeExportModal"
                  class="btn btn-ghost btn-sm btn-circle"
                  :disabled="isExporting"
                >
                  <PhX :size="20" />
                </button>
              </div>
            </slot>

            <!-- 模态框内容插槽 -->
            <slot
              name="modal-content"
              :export-options="exportOptions"
              :export-error="exportError"
              :export-progress="exportProgress"
              :is-exporting="isExporting"
              :default-filename="defaultFilename"
            >
              <div class="modal-content p-6 overflow-y-auto max-h-[calc(90vh-140px)]">
                <!-- 错误提示 -->
                <div v-if="exportError" class="alert alert-error mb-6">
                  <PhWarning :size="20" />
                  <span>{{ exportError }}</span>
                </div>

                <!-- 进度提示 -->
                <div v-if="exportProgress" class="alert alert-info mb-6">
                  <PhSpinner :size="20" class="animate-spin" />
                  <span>{{ exportProgress }}</span>
                </div>

                <!-- 文件名设置 -->
                <div class="form-control mb-6">
                  <label class="label">
                    <span class="label-text font-semibold">文件名</span>
                  </label>
                  <input
                    v-model="exportOptions.filename"
                    type="text"
                    class="input input-bordered w-full"
                    placeholder="输入文件名（不含扩展名）"
                    :disabled="isExporting"
                  />
                  <p class="text-xs text-base-content/60 mt-1">文件将自动添加 .md 后缀</p>
                </div>

                <!-- 导出格式说明 -->
                <div class="format-info mb-6">
                  <h3 class="text-lg font-semibold mb-4">导出格式</h3>
                  <div class="format-option p-4 border-2 border-primary/30 bg-primary/5 rounded-lg">
                    <div class="flex items-center gap-3">
                      <PhFileText :size="24" class="text-blue-600" />
                      <div>
                        <div class="flex items-center gap-2 mb-1">
                          <span class="font-medium">Markdown</span>
                          <span class="text-xs text-base-content/60">.md</span>
                        </div>
                        <p class="text-sm text-base-content/70">纯文本格式，适合编辑和版本控制</p>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 导出选项 -->
                <div class="export-options mb-6">
                  <h3 class="text-lg font-semibold mb-4">导出选项</h3>
                  <div class="space-y-4">
                    <label
                      class="toggle-option flex items-center justify-between p-3 bg-base-200/50 rounded-lg"
                    >
                      <div>
                        <span class="font-medium">包含元数据</span>
                        <p class="text-sm text-base-content/60">包含作者、发布时间、标签等信息</p>
                      </div>
                      <input
                        v-model="exportOptions.includeMetadata"
                        type="checkbox"
                        class="toggle toggle-primary"
                        :disabled="isExporting"
                      />
                    </label>
                  </div>
                </div>
              </div>
            </slot>

            <!-- 模态框底部插槽 -->
            <slot
              name="modal-footer"
              :close-modal="closeExportModal"
              :perform-export="performExport"
              :is-exporting="isExporting"
              :can-export="canExport"
            >
              <div
                class="modal-footer flex items-center justify-between p-6 border-t border-base-300"
              >
                <div class="export-info">
                  <p class="text-sm text-base-content/70">将导出为 Markdown 格式 (.md)</p>
                </div>
                <div class="actions flex gap-3">
                  <button @click="closeExportModal" class="btn btn-ghost" :disabled="isExporting">
                    取消
                  </button>
                  <button @click="performExport" class="btn btn-primary" :disabled="!canExport">
                    <PhSpinner v-if="isExporting" :size="16" class="animate-spin" />
                    <PhCheck v-else :size="16" />
                    <span>{{ isExporting ? '导出中...' : '开始导出' }}</span>
                  </button>
                </div>
              </div>
            </slot>
          </div>
        </Transition>
      </div>
    </Transition>
  </div>
</template>

<style scoped lang="scss">
/* 导出组件样式 */
.article-exporter {
  .export-trigger {
    display: flex;
    align-items: center;
  }
}

/* 导出按钮增强样式 */
.export-btn {
  position: relative;
  overflow: hidden;
  font-weight: 500;
  letter-spacing: 0.025em;

  /* 渐变背景效果 */
  &.btn-outline {
    background: linear-gradient(135deg, transparent 0%, hsl(var(--p) / 0.05) 100%);
    border: 1.5px solid hsl(var(--p) / 0.3);

    &:hover {
      background: linear-gradient(135deg, hsl(var(--p) / 0.1) 0%, hsl(var(--p) / 0.15) 100%);
      border-color: hsl(var(--p));
      transform: translateY(-1px);
    }
  }

  &.btn-primary {
    background: linear-gradient(135deg, hsl(var(--p)) 0%, hsl(var(--p) / 0.8) 100%);

    &:hover {
      background: linear-gradient(135deg, hsl(var(--p) / 0.9) 0%, hsl(var(--p) / 0.7) 100%);
      transform: translateY(-1px);
    }
  }

  &.btn-ghost {
    background: transparent;

    &:hover {
      background: hsl(var(--p) / 0.1);
      color: hsl(var(--p));
    }
  }

  /* 禁用状态 */
  &:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none !important;
  }

  /* 图标和文字对齐 */
  .export-btn-text {
    display: inline-flex;
    align-items: center;
  }

  /* 加载状态 */
  &:has(.animate-spin) {
    cursor: wait;
  }

  /* 响应式调整 */
  @media (max-width: 640px) {
    &.btn-sm {
      padding: 0.375rem 0.75rem;
      font-size: 0.875rem;
    }

    &.btn-xs {
      padding: 0.25rem 0.5rem;
      font-size: 0.75rem;
    }
  }
}

/* 模态框样式 */
.export-modal {
  animation: modalSlideIn 0.3s ease-out;
}

@keyframes modalSlideIn {
  from {
    opacity: 0;
    transform: translateY(-20px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

.format-option {
  display: flex;
  align-items: flex-start;
  padding: 1rem;
  border: 2px solid hsl(var(--b3));
  border-radius: 0.75rem;
  transition: all 0.2s ease;

  &:hover {
    border-color: hsl(var(--p) / 0.3);
    background: hsl(var(--p) / 0.05);
  }

  &:has(input:checked) {
    border-color: hsl(var(--p));
    background: hsl(var(--p) / 0.1);
  }
}

.toggle-option {
  padding: 0.75rem 0;
  border-bottom: 1px solid hsl(var(--b3) / 0.3);

  &:last-child {
    border-bottom: none;
  }
}

/* 响应式设计 */
@media (max-width: 640px) {
  .export-modal {
    margin: 1rem;
    width: calc(100% - 2rem);
  }

  .modal-content {
    max-height: calc(90vh - 120px);
  }

  .format-option {
    padding: 0.75rem;
  }

  .modal-footer {
    flex-direction: column;
    gap: 1rem;
    align-items: stretch;

    .selected-formats {
      text-align: center;
    }

    .actions {
      justify-content: center;
    }
  }
}

/* 动画效果 */
.format-option {
  animation: fadeInUp 0.3s ease-out;
}

@keyframes fadeInUp {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
</style>
